package com.fsoft.manager.user.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.fsoft.core.Global;
import com.fsoft.core.annotation.SystemLog;
import com.fsoft.core.common.QueryParam;
import com.fsoft.core.common.base.contorller.BaseController;
import com.fsoft.core.common.exceptions.RRException;
import com.fsoft.core.utils.DateTimeUtils;
import com.fsoft.core.utils.OgnlUtils;
import com.fsoft.core.utils.RetVo;
import com.fsoft.manager.user.entity.SysUser;
import com.fsoft.manager.user.service.SysUserService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

/**
 * @package com.fsoft.manager.user.controller
 * @author Fish
 * @email it.fish2010@foxmail.com
 * @create 2019-05-06
 * @copyright 2009-2019
 */
@Controller
@RequestMapping("/sys-user")
public class SysUserController extends BaseController {
	@Autowired
	private SysUserService userService;

	/**
	 * 所有用户列表
	 * 
	 * @user fish(it.fish2010@foxmail.com)
	 * @date 2019-10-09
	 * @param params
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping("/findList")
	public RetVo findList(@RequestParam Map<String, Object> params) throws Exception {
		QueryParam query = new QueryParam(params);
		// 非默认单位的时候，只允许查询本单位的用户
		String currOrgId = getUser().getOrgId();
		if (OgnlUtils.isEmpty(params.get(Global.F_ORGID)) && !Global.DEFAULT_ORG_ID.equalsIgnoreCase(currOrgId))
			query.setOrgId(currOrgId);
		if (!getUser().isSuperAdmin()) {
			query.put("notAdmin", "true");
		}
		Page<SysUser> page = PageHelper.startPage(query.getPage(), query.getLimit());
		List<SysUser> userList = userService.findList(query);
		return RetVo.ok(page.getTotal(), userList);
	}

	/** 跳转到添加页面 */
	@RequestMapping("/list")
	@RequiresPermissions("sys:user:list")
	public String list() {
		return "/fsoft-web/user/sysuser-list";
	}

	/** 跳转到添加页面 */
	@GetMapping("/page/{page}")
	public ModelAndView page(@PathVariable("page") String pageName) throws Exception {
		if (StringUtils.equals(pageName, "list"))
			pageName = "sysuser-list";
		ModelAndView mv = new ModelAndView("/fsoft-web/user/" + pageName);
		mv.addObject("user", getUser());
		return mv;
	}

	/***
	 * F-Soft 跳转到添加页面，如果orgId不为空（树形选中），需要把orgId带入到编辑界面
	 * 
	 * @author it_software(it.fish2010@foxmail.com)
	 * @date 2020-02-16
	 * @param orgId
	 * @param model
	 * @return
	 */
	@RequestMapping(value = { "/add", "/add/{orgId}" })
	public String add(@PathVariable(required = false, value = "orgId") String orgId, Model model) {
		if (StringUtils.isNotBlank(orgId)) {
			SysUser o_user = new SysUser();
			o_user.setOrgId(orgId);
			model.addAttribute("user", o_user);
		}
		return "/fsoft-web/user/sysuser-modify";
	}

	@RequestMapping("/edit/{id}")
	@RequiresPermissions("sys:user:edit")
	public String edit(HttpServletRequest request, Model model, @PathVariable("id") String id) throws Exception {
		SysUser user = userService.getEntity(id);
		model.addAttribute("user", user);
		return "/fsoft-web/user/sysuser-modify";
	}

	/**
	 * F-Soft 跳转到修改密码界面
	 * 
	 * @author it_software(it.fish2010@foxmail.com)
	 * @date 2020-02-16
	 * @param request
	 * @param model
	 * @param id
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/resetpwd/{id}")
	@RequiresPermissions("sys:user:edit")
	public String resetpwd(Model model, @PathVariable("id") String id) throws Exception {
		if (StringUtils.isBlank(id))
			return Global.ERROR_PARE_404;
		model.addAttribute("ids", id);
		return "/fsoft-web/user/sysuser-resetpwd";
	}

	/** 重置当前用户密码（登录用户自己修改密码） */
	@RequestMapping("/resetpwd")
	public String resetpwd(Model model) throws Exception {
		if (OgnlUtils.isEmpty(getUser()))
			throw new Exception("未登录!");
		model.addAttribute("userId", getUser().getId());
		return "/fsoft-web/user-resetpwd";
	}

	/** 获取登录的用户信息 */
	@ResponseBody
	@RequestMapping("/info")
	public RetVo info() {
		return RetVo.ok().put("user", getUser());
	}

	/***
	 * F-Soft 修改登录用户密码
	 * 
	 * @author Fish(it.fish2010@foxmail.com)
	 * @date 2019-12-11
	 * @param password
	 * @param newPassword
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@SystemLog("修改密码")
	@RequestMapping("/modifyPwd")
	public RetVo modifyPwd(@RequestBody SysUser param) throws Exception {
		String ids = param.getId();
		if (StringUtils.isBlank(ids))
			return RetVo.error("无法识别的帐号标识，请刷新后重试");
		try {
			String[] userIds = ids.split(",");
			String loginPwd = param.getLoginPwd();
			if (StringUtils.isBlank(loginPwd))
				throw new Exception("密码为空");
			// 解密获取明文
			loginPwd = Base64.decodeToString(loginPwd);
			// 更新密码
			for (String userId : userIds) {
				userService.modifyLoginPwd(userId, loginPwd);
			}
			return RetVo.ok();
		} catch (Exception e) {
			return RetVo.error(e.getMessage());
		}
	}

	/**
	 * F-Soft 用户详情
	 * 
	 * @author Fish(it.fish2010@foxmail.com)
	 * @date 2019-11-29
	 * @param userId
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping("/info/{userId}")
	@RequiresPermissions("sys:user:info")
	public RetVo info(@PathVariable("userId") String userId) throws Exception {
		SysUser user = userService.getEntity(userId);
		return RetVo.ok(1L, user);
	}

	/***
	 * F-Soft 保存用户(新增)
	 * 
	 * @author Fish(it.fish2010@foxmail.com)
	 * @date 2019-11-29
	 * @param user
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@SystemLog("保存用户")
	@RequestMapping(value = "/save", method = RequestMethod.PUT)
	public RetVo save(@RequestBody SysUser user) throws Exception {
		SysUser existUser = userService.getSysUserByLoginAcct(user.getLoginAcct());
		if (existUser != null) {
			throw new Exception("帐号【" + user.getLoginAcct() + "】已经存在");
		}
		// 默认密码(Controller 不允许对密码加密)
		if (StringUtils.isBlank(user.getLoginPwd()))
			user.setLoginPwd(Global.DEFAULT_PWD);
		if (OgnlUtils.isNotEmpty(user.getRoleIdList()))
			user.setRoleIdList(buildStrList(user.getRoleIdList()));
		user.setCreateUserId(getUserId());
		user.setCreateTime(DateTimeUtils.getNowTime());
		user.setAreaId(getUser().getAreaId());
		userService.save(user);
		return RetVo.ok();
	}

	/***
	 * F-Soft 修改用户(更新)
	 * 
	 * @author Fish(it.fish2010@foxmail.com)
	 * @date 2019-11-29
	 * @param user
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@SystemLog("修改用户")
	@RequestMapping(value = "/modify", method = RequestMethod.PUT)
	public RetVo modify(@RequestBody SysUser user) throws Exception {
		if (StringUtils.equals(user.getId(), Global.SYS_USER_ADMIN_ID)) {
			user.setLoginAcct(null); // 如果是超级管理员帐号，不允许修改登录名
		}
		SysUser entity = userService.getEntity(user.getId());
		if (entity == null)
			return RetVo.error("用户信息已更新，请刷新后重试");
		if (OgnlUtils.isNotEmpty(user.getRoleIdList()))
			user.setRoleIdList(buildStrList(user.getRoleIdList()));
		if (StringUtils.isBlank(user.getOrgId()))
			user.setOrgId(getUser().getOrgId());
		try {
			user.setModifyUserId(getUserId());
			user.setModifyTime(DateTimeUtils.getNowTime());
			userService.modify(user);
			if (StringUtils.equals(user.getId(), getUser().getId())) { // 如果编辑的是当前登录用户
				if (StringUtils.isNotBlank(user.getName()))
					getUser().setName(user.getName());
				if (StringUtils.isNotBlank(user.getMobile()))
					getUser().setMobile(user.getMobile());
				if (StringUtils.isNotBlank(user.getEmail()))
					getUser().setEmail(user.getEmail());
				if (StringUtils.isNotBlank(user.getTheme()))
					getUser().setCurrTheme(user.getTheme());
			}
			return RetVo.ok();
		} catch (Exception e) {
			return RetVo.error(e.getMessage());
		}
	}

	@SystemLog("锁定账号")
	@ResponseBody
	@RequestMapping("/lock")
	@RequiresPermissions("sys:user:lock")
	public RetVo lock(@RequestBody String[] ids) throws Exception {
		List<SysUser> list = new ArrayList<SysUser>();
		for (String id : ids) {
			if (StringUtils.equals(id, getUserId()))
				throw new Exception("不允许对自己加锁，请重新选择！");
			SysUser user = new SysUser();
			user.setId(id);
			user.setIsLock(Global.STATUS_YES);
			user.setLockType(Global.LOCK_TYPE_ADMIN);
			user.setLockTime(DateTimeUtils.getNowTime());
			user.setModifyUserId(getUserId());
			user.setModifyTime(DateTimeUtils.getNowTime());
			list.add(user);
		}
		userService.lockUser(list);
		return RetVo.ok();
	}

	@ResponseBody
	@SystemLog("解锁帐号")
	@RequestMapping("/unlock")
	@RequiresPermissions("sys:user:unlock")
	public RetVo unlock(@RequestBody String[] ids) throws Exception {
		List<SysUser> list = new ArrayList<SysUser>();
		for (String id : ids) {
			if (StringUtils.equals(id, getUserId()))
				throw new Exception("不允许自己解锁，请联系其他管理员！");
			SysUser user = new SysUser();
			user.setId(id);
			user.setModifyUserId(getUserId());
			user.setModifyTime(DateTimeUtils.getNowTime());
			list.add(user);
		}
		userService.unlockUser(list);
		return RetVo.ok();
	}

	/***
	 * F-Soft 帐号启用
	 * 
	 * @author Fish(it.fish2010@foxmail.com)
	 * @date 2019-11-16
	 * @param ids
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@SystemLog("帐号启用")
	@RequestMapping("/enable")
	@RequiresPermissions("sys:user:enable")
	public RetVo enable(@RequestBody String[] ids) throws Exception {
		for (String id : ids) {
			SysUser entity = new SysUser();
			entity.setId(id);
			entity.setStatus(Global.STATUS_YES);
			entity.setModifyUserId(getUserId());
			entity.setModifyTime(DateTimeUtils.getNowTime());
			userService.modify(entity);
		}
		return RetVo.ok();
	}

	/***
	 * F-Soft 帐号禁用
	 * 
	 * @author Fish(it.fish2010@foxmail.com)
	 * @date 2019-11-16
	 * @param ids
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@SystemLog("帐号禁用")
	@RequestMapping("/disable")
	@RequiresPermissions("sys:user:enable")
	public RetVo disable(@RequestBody String[] ids) throws Exception {
		for (String id : ids) {
			SysUser entity = new SysUser();
			entity.setId(id);
			entity.setStatus(Global.STATUS_NO);
			entity.setModifyUserId(getUserId());
			entity.setModifyTime(DateTimeUtils.getNowTime());
			userService.modify(entity);
		}
		return RetVo.ok();
	}

	/**
	 * 删除用户
	 * 
	 * @throws Exception
	 */
	@ResponseBody
	@SystemLog("删除用户")
	@RequestMapping("/remove")
	@RequiresPermissions("sys:user:remove")
	public RetVo remove(@RequestBody String[] userIds) throws Exception {
		if (ArrayUtils.contains(userIds, Global.SYS_USER_ADMIN_ID)) {
			return RetVo.error("系统管理员不能删除");
		}
		if (ArrayUtils.contains(userIds, getUserId())) {
			return RetVo.error("当前用户[" + getLoginAcct() + "]已登录，不能删除!");
		}
		userService.removeBatch(Arrays.asList(userIds));
		return RetVo.ok();
	}

	/**
	 * 初始化密码
	 * 
	 * @throws Exception
	 */
	@ResponseBody
	@SystemLog("初始化密码")
	@RequestMapping("/initPassword")
	@RequiresPermissions("sys:user:init:password")
	public RetVo initPassword(@RequestBody String[] userIds) throws Exception {
		userService.initPassword(userIds);
		return RetVo.ok();
	}

	/***
	 * 把登录会话信息返回前端
	 * 
	 * @author Fish
	 * @date 2021-04-27
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping(value = "/getCurrentUserInfo", method = RequestMethod.POST)
	public RetVo getCurrentUserInfo() throws Exception {
		return RetVo.ok(getUser());
	}

	@ResponseBody
	@RequestMapping(value = { "/passworkCheck" }, method = RequestMethod.POST)
	public RetVo checkPassword(@RequestBody SysUser user) throws Exception {
		if (StringUtils.isBlank(user.getLoginPwd()))
			throw new Exception("原密码为空");
		if (StringUtils.isBlank(user.getId()))
			throw new RRException("ids标识为空");
		SysUser u = userService.getEntity(user.getId());
		if (u == null)
			throw new RRException("用户信息已被删除，请重新登录！");
		String loginPwd = Base64.decodeToString(user.getLoginPwd()); // 获取明文
		loginPwd = new Sha256Hash(loginPwd).toHex();
		// 密文比较
		if (StringUtils.equals(u.getLoginPwd(), loginPwd))
			return RetVo.ok();
		return RetVo.error("原密码校验失败！");
	}

	protected final List<String> buildStrList(List<String> list) {
		List<String> strList = new ArrayList<String>();
		for (String str : list) {
			String[] s = str.split(",");
			strList.addAll(Arrays.asList(s));
		}
		return strList;
	}

}
